﻿using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Modelo;
using Control;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Threading;
using Grafo;

namespace UnitTestProject1
{
    [TestClass]
    public class Pruebas
    {
        private static bool termino = false;
        private static Simulacion simulacion;
        private static Aplicacion aplicacion;
        private static BackgroundWorker bw_Estaciones, bw_Lineas, bw_LineaArcos, bw_LineaStop, bw_Arcos, bw_Instanciacion;

        [ClassInitialize()]
        public static void CargarDatos(TestContext test)
        {
            
            aplicacion = new Aplicacion();
            simulacion = aplicacion.darSimulacion();
            string camino = "D:/Workspace Visual Studio/ProyectoIntegrador1/recursos";
            aplicacion.setCamino(camino);

            bw_Estaciones = new BackgroundWorker();
            bw_Estaciones.WorkerSupportsCancellation = false;
            bw_Estaciones.WorkerReportsProgress = true;
            bw_Estaciones.DoWork += new DoWorkEventHandler(aplicacion.bw_DoWorkEstaciones);
            bw_Estaciones.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompletedEstaciones);

            bw_Arcos = new BackgroundWorker();
            bw_Arcos.WorkerSupportsCancellation = false;
            bw_Arcos.WorkerReportsProgress = true;
            bw_Arcos.DoWork += new DoWorkEventHandler(aplicacion.bw_DoWorkArcos);
            bw_Arcos.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompletedArco);

            bw_LineaStop = new BackgroundWorker();
            bw_LineaStop.WorkerSupportsCancellation = false;
            bw_LineaStop.WorkerReportsProgress = true;
            bw_LineaStop.DoWork += new DoWorkEventHandler(aplicacion.bw_DoWorkLineasStops);
            bw_LineaStop.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompletedLineaStop);

            bw_LineaArcos = new BackgroundWorker();
            bw_LineaArcos.WorkerSupportsCancellation = false;
            bw_LineaArcos.WorkerReportsProgress = true;
            bw_LineaArcos.DoWork += new DoWorkEventHandler(aplicacion.bw_DoWorkLineaArcos);
            bw_LineaArcos.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompletedLineaArco);

            bw_Lineas = new BackgroundWorker();
            bw_Lineas.WorkerSupportsCancellation = false;
            bw_Lineas.WorkerReportsProgress = true;
            bw_Lineas.DoWork += new DoWorkEventHandler(aplicacion.bw_DoWorkLineas);
            bw_Lineas.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompletedLinea);

            bw_Instanciacion = new BackgroundWorker();
            bw_Instanciacion.WorkerSupportsCancellation = false;
            bw_Instanciacion.WorkerReportsProgress = true;
            bw_Instanciacion.DoWork += new DoWorkEventHandler(aplicacion.bw_DoWorkInstanciacion);
            bw_Instanciacion.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompletedInstanciacion);

            if (File.Exists(camino + "//ARCS.txt") && File.Exists(camino + "//STOPS.txt") && File.Exists(camino + "//LINES.txt") && File.Exists(camino + "//LINESTOPS.txt") && File.Exists(camino + "//LINESARCS.txt"))
            {

                if (bw_Estaciones.IsBusy != true)
                {
                    bw_Estaciones.RunWorkerAsync();
                }
                while (!termino)
                {
                    Thread.Sleep(1);
                }
            }
            else
            {
                Assert.Fail("Faltan archivos.");
            }
        }

        [TestMethod]
        public void PruebaInstanciasRutas()
        {
            List<Ruta> rutas = simulacion.darRutasDef();
            Assert.IsTrue(rutas.Count > 0, "La lista de rutas deberia contener por lo menos un elemento");
            Ruta rutaPrueba = null;
            int i = 0;
            for (; i < rutas.Count; i++)
            {
                if (rutas[i].darId().Equals("131"))
                {
                    rutaPrueba = rutas[i];
                    break;
                }
            }
            Assert.IsNotNull(rutaPrueba, "Deberia existir la ruta T31");
            Grafo<Estacion> grafoEstaciones = simulacion.darEstacionesRutas()[i];
            List<Estacion> estaciones =  grafoEstaciones.darVertices();
            Estacion estacionPrueba = null;
            for (int j = 0; j < estaciones.Count; j++)
            {
                if (estaciones[j].darNombre().Equals("Refugio")) 
                {
                    estacionPrueba = estaciones[j];
                }
            }
            Assert.IsNotNull(estacionPrueba, "La ruta T31 deberia tener la estacion Refugio");
        }

        [TestMethod]
        public void PruebaInstanciasEstaciones()
        {
            //error no esta cargando los archivos.
            List<Estacion> estaciones = simulacion.darEstacionesDefinitivas();
            Assert.IsTrue(estaciones.Count > 0, "El arreglo de estaciones deberia ser mayor a 0");
            Estacion estacionPrueba = null;
            for(int i = 0; i<estaciones.Count; i++)
            {
                if (estaciones[i].darNombre().Equals("Villa Colombia")){
                    estacionPrueba = estaciones[i];
                    break;
                }
            }
            Assert.IsNotNull(estacionPrueba, "Deberia existir la estacion Villa Colombia");
        }

        [TestMethod]
        public void PruebaCargaRuta()
        {
            Dictionary<string, string> dic = simulacion.darLineas();
            List<string> valores = new List<string>();
            foreach (KeyValuePair<string, string> val in dic)
            {
                if (!valores.Contains(val.Value))
                    valores.Add(val.Value);
            }
            Assert.AreEqual(valores.Count, 11);
            Assert.IsTrue(dic["131"].Equals("\"T31\""));
            Assert.IsTrue(dic["421"].Equals("\"E21\""));
            Assert.IsTrue(dic["1471"].Equals("\"T47A\""));
        }

        [TestMethod]
        public void PruebaCargaEstaciones()
        {
            Dictionary<string, string> dic = simulacion.darEstaciones();
            List<string> valores = new List<string>();
            foreach(KeyValuePair<string, string> val in dic)
            {
                if (!valores.Contains(val.Value))
                    valores.Add(val.Value);
            }
            Assert.AreEqual(valores.Count, 58);
            Assert.IsTrue(dic.ContainsValue("Terminal Andres Sanin"));
            Assert.IsTrue(dic.ContainsValue("Popular"));
            Assert.IsTrue(dic.ContainsValue("Universidades"));
        }


        private static void bw_RunWorkerCompletedEstaciones(object sender, RunWorkerCompletedEventArgs e)
        {
                if (bw_Lineas.IsBusy != true)
                {
                    bw_Lineas.RunWorkerAsync();
                }
        }

        private static void bw_RunWorkerCompletedArco(object sender, RunWorkerCompletedEventArgs e)
        {
                if (bw_Instanciacion.IsBusy != true)
                {
                    bw_Instanciacion.RunWorkerAsync();
                }
        }

        private static void bw_RunWorkerCompletedLineaArco(object sender, RunWorkerCompletedEventArgs e)
        {   
                if (bw_Arcos.IsBusy != true)
                {
                    bw_Arcos.RunWorkerAsync();
                }
        }

        private static void bw_RunWorkerCompletedLineaStop(object sender, RunWorkerCompletedEventArgs e)
        {
        
                bw_LineaArcos.RunWorkerAsync();
        }

        private static void bw_RunWorkerCompletedLinea(object sender, RunWorkerCompletedEventArgs e)
        {
           
                bw_LineaStop.RunWorkerAsync();
        }

        private static void bw_RunWorkerCompletedInstanciacion(object sender, RunWorkerCompletedEventArgs e)
        {
            Thread.Sleep(1000);
            termino = true;
        }


    }
}
